#pragma once
#include <iostream>
#include <queue>
#include <vector>
#include <pthread.h>
#include "Sem.hpp"
#include "Mutex.hpp"
using namespace Mutex;
const int defultvalue = 1;
template <typename T>
class RingQueue
{
private:
    // void Lock(MyMutex& _mutex)
    // {
    //     //pthread_mutex_lock(&_mutex);
    //     _mutex.Lock();
    // }
    // void Unlock(MyMutex& _mutex)
    // {
    //     //pthread_mutex_unlock(&_mutex);
    //     _mutex.UnLock();
    // }
public:
    RingQueue(int cap = defultvalue)
        : _q(cap),
          _cap(cap),
          _productor_step(0),
          _consumer_step(0),
          _room_sem(cap),
          _data_sem(0)
    {
        //pthread_mutex_init(&_productor_mutex, nullptr);
        //pthread_mutex_init(&_consumer_mutex, nullptr);
    }
    void Equeue(T &data)
    {
        _room_sem.P();

        {
            LockGuard lock(_productor_mutex);
            // Lock(_productor_mutex);
            _q[_productor_step] = data;
            _productor_step++;
            _productor_step %= _cap;
            _data_sem.V();
            // Unlock(_productor_mutex);
        }
    }
    T Pop()
    {
        _data_sem.P();
        T ret;
        {
            LockGuard lock(_consumer_mutex);
            // Lock(_consumer_mutex);
            ret = _q[_consumer_step];
            _consumer_step++;
            _consumer_step %= _cap;
            _room_sem.V();
            // Unlock(_consumer_mutex);
        }
        return ret;
    }

private:
    // 1.定义一个队列
    std::vector<T> _q;
    int _cap;
    // 2.生产者消费者当前下标
    int _productor_step;
    int _consumer_step;

    // 3.定义信号量
    Sem _room_sem;
    Sem _data_sem;
    // 4.定义锁，为多生产者多消费者使用
    MyMutex _productor_mutex;
    MyMutex _consumer_mutex;
};